package com.zeratul.common.event.base;


import cn.hutool.core.util.ObjectUtil;
import com.zeratul.common.core.utils.spring.SpringUtils;
import com.zeratul.common.event.base.interceptor.BaseSubscribeInterceptor;
import com.zeratul.common.event.domain.ZtEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.Map;

/**
 * 订阅者-服务层接口
 * author Ken
 * create_time 2022/9/17
 */
public interface BaseSubscribeServer {

    Logger log = LoggerFactory.getLogger(BaseSubscribeServer.class);

    /**
     * 服务层事件处理
     * @param ztEvent
     * @param <T>
     */
    <T> void eventHandler(ZtEvent<T> ztEvent);

    /**
     * 服务层拦截器处理
     */
    default <T> ZtEvent<T> doInterceptor(ZtEvent<T> ztEvent) {

        //设置事件达到时间
        ztEvent.setRecvTime(new Date());

        //获取所有订阅者拦截器
        Map<String, BaseSubscribeInterceptor> subscribeInterceptors = SpringUtils.getBeansOfType(BaseSubscribeInterceptor.class);
        //进行消费者拦截器的相关处理
        if(ObjectUtil.isEmpty(subscribeInterceptors)){
            return ztEvent;
        }

        for (BaseSubscribeInterceptor subscribeInterceptor : subscribeInterceptors.values()) {
            try {
                //依次判断拦截器是否可以执行
                if (!subscribeInterceptor.isSupport(ztEvent)) {
                    continue;
                }
                //调用拦截器处理消息
                ztEvent = subscribeInterceptor.interceptor(ztEvent);
            } catch (Exception e) {
                log.error("【事件总线】订阅者端拦截器异常！事件：{} 拦截器：{}", ztEvent, subscribeInterceptor.getClass().getName(), e);
            }
        }

        //判断消息是否过期，如果过期，则不再处理
        if (ztEvent.isExpire()) {
            return null;
        }
        return ztEvent;
    }
}
